package com.marklogic.ps.servicetester.services;

import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.Namespace;
import org.jdom.input.SAXBuilder;

import com.marklogic.ps.servicetester.domain.Query;
import com.marklogic.ps.servicetester.domain.ServerConnectionInfo;
import com.marklogic.ps.servicetester.domain.Service;

public class ServicesServiceImpl implements ServicesService {

	protected final static Logger logger = Logger
			.getLogger(ServicesServiceImpl.class);
	
	private final static Namespace DEFAULT_NAMESPACE = Namespace.getNamespace("");
	
	//private static XStream xstream = new XStream(new DomDriver());

	/* (non-Javadoc)
	 * @see com.marklogic.cq.ServicesService#getServices(java.lang.String)
	 */
	public List<Service> getServices(ServerConnectionInfo sci) throws Exception {
		List<Service> services = new ArrayList<Service>();
		try {
//			xstream.alias("results", List.class);
//			xstream.alias("service", Service.class);
//			xstream.alias("queries", List.class);
//			xstream.alias("query", Query.class);
//			xstream.alias("request", org.w3c.dom.Document.class);
//			xstream.alias("request", String.class);
//			//xstream.alias("xquery-path", String.class);
//			//xstream.aliasField("xquery-path", Service.class, "xqueryPath");
//			xstream.registerConverter(new DomConverter());
//			//xstream.registerConverter(new QueryConverter());
			ServiceHelper serviceHelper = new ServiceHelper(sci);
			String xml = serviceHelper.getServices();
			
			
			SAXBuilder builder = new SAXBuilder();
			Document doc = builder.build(new StringReader(xml));
			Element root = doc.getRootElement();
			
			List<Element> serviceElements = root.getChildren();
			for (Element serviceElement : serviceElements) {
				Service service = new Service();
				services.add(service);
				service.setName(serviceElement.getChild("name").getText());
				service.setXqueryPath(serviceElement.getChild("xqueryPath").getText());
				List<Query> queries = new ArrayList<Query>();
				service.setQueries(queries);
				
			  //Default localname/namespace for the request element
			  String localname = "request";
			  Namespace namespace = DEFAULT_NAMESPACE;
				Element localnameElement = serviceElement.getChild("request-element-localname");
        Element namespaceElement = serviceElement.getChild("request-element-namespace");
        if (localnameElement != null) {
          localname = localnameElement.getText();
          if (namespaceElement != null) {
            namespace = Namespace.getNamespace(namespaceElement.getText());
          }
        }
				
				List<Element> queryElements = serviceElement.getChild("queries").getChildren();
				
				for (Element queriesElement : queryElements) {
					Query query = new Query();
					query.setName(queriesElement.getAttribute("name").getValue());
					Element requestElement = null;
					List children = queriesElement.getContent();
					for (Object child : children) {
						if (child instanceof Element) {
							requestElement = (Element)child;
							break;
						}
					}
					//query.setName(queriesElement.getChild("name").getText());
					
					//Element requestElement = queriesElement.getChild(localname, namespace);
					query.setRequestElement(requestElement);
					queries.add(query);
					query.setService(service);
				}
				System.out.println(serviceElement);
			}
			
//			services = (List<Service>)xstream.fromXML(xml);
//			
//			// Is there a better way to tell XStream to populate back-references?
//			for (Service service : services) {
//				for (Query query : service.getQueries()) {
//					query.setService(service);
//				}
//			}
			
			return services;
		} catch (Exception e) {
		  throw new Exception("Error fetching services: " + e.getMessage(), e);
		}
	}

}
